Imports iSoft.Common.Utility

Namespace Component

    Public Class RichTextBoxPlus
        Inherits Windows.Forms.RichTextBox

        Private m_blnInit As Boolean
        Private m_FileName As String
        Private m_htEncodings As Hashtable

        Private WithEvents m_cmEncodings As Windows.Forms.ContextMenu

        ''' <summary>
        ''' The event when the line be added into the RichTextbox.
        ''' </summary>
        ''' <param name="sender">RichTextbox object.</param>
        ''' <param name="e">BeforeLineAddEventArgs.</param>
        ''' <remarks></remarks>
        Public Event BeforeLineAdd(ByVal sender As Object, ByVal e As BeforeLineAddEventArgs)

        ''' <summary>
        ''' The file full name to load.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property FileName() As String
            Get
                Return m_FileName
            End Get
        End Property

        ''' <summary>
        ''' The current cursor line number.
        ''' </summary>
        ''' <value></value>
        ''' <returns>Return the current cursor line number.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property CurrentCursorLine() As Integer
            Get
                Dim ret As Integer = 0
                If m_blnInit = False Then
                    ret = Me.GetLineFromCharIndex(Me.SelectionStart) + 1
                End If
                Return ret
            End Get
        End Property

        ''' <summary>
        ''' Create the encoding context menu item.
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub CreateEncodingMenuItems()
            'Create context menu and set to the richtextbox
            m_cmEncodings = New Windows.Forms.ContextMenu
            Me.ContextMenu = m_cmEncodings
            'Load the encodings installed into current system
            Dim ci As Globalization.CultureInfo
            Dim enc As System.Text.Encoding
            Dim mi As Windows.Forms.MenuItem
            For Each ci In Globalization.CultureInfo.GetCultures(Globalization.CultureTypes.InstalledWin32Cultures)
                enc = System.Text.Encoding.GetEncoding(ci.TextInfo.ANSICodePage)
                If m_htEncodings.Contains(enc.EncodingName) = False Then
                    m_htEncodings.Add(enc.EncodingName, enc)
                    mi = New Windows.Forms.MenuItem(enc.EncodingName, AddressOf OnContextMenuItemsClick)
                    mi.RadioCheck = True
                    m_cmEncodings.MenuItems.Add(mi)
                End If
            Next
        End Sub

        ''' <summary>
        ''' Create instance.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
            MyBase.New()

            [ReadOnly] = True
            WordWrap = False
            m_FileName = ""
            m_blnInit = False
            m_htEncodings = New Hashtable

            CreateEncodingMenuItems()
        End Sub

        ''' <summary>
        ''' Load the file into the RichTextbox
        ''' </summary>
        ''' <param name="FileName">The full file name.</param>
        ''' <param name="enc">The load encoding.</param>
        ''' <remarks></remarks>
        Private Sub Load(ByVal FileName As String, ByVal enc As Text.Encoding)
            Dim fr As FileReader
            Dim line As String
            Try
                m_blnInit = True
                m_FileName = FileName
                MyBase.Clear()

                If enc Is Nothing Then
                    'System default encoding
                    fr = New FileReader(FileName, True)
                    RadioCheckEncodingItem(fr.CurrentEncoding)
                Else
                    'Specify encoding by param
                    fr = New FileReader(FileName, enc, True)
                End If
                If Not fr Is Nothing Then
                    For Each line In fr.Comments
                        OnBeforeLineAdded(line)
                    Next
                    SelectionStart = 0
                End If
            Catch ex As Exception
                m_FileName = ""
            Finally
                m_blnInit = False
            End Try
        End Sub

        ''' <summary>
        ''' Radioativly check the encoding menu item. Uncheck all other items.
        ''' </summary>
        ''' <param name="enc">Checked encoding.</param>
        ''' <remarks></remarks>
        Private Sub RadioCheckEncodingItem(ByVal enc As Text.Encoding)
            Dim mi As Windows.Forms.MenuItem
            For Each mi In ContextMenu.MenuItems
                If String.Compare(mi.Text, enc.EncodingName, True) = 0 AndAlso m_htEncodings.Contains(enc.EncodingName) = True Then
                    mi.Checked = True
                Else
                    mi.Checked = False
                End If
            Next
        End Sub

        ''' <summary>
        ''' Load the file.
        ''' </summary>
        ''' <param name="FileName">The full file name.</param>
        ''' <remarks></remarks>
        Public Sub Load(ByVal FileName As String)
            Load(FileName, Nothing)
        End Sub

        ''' <summary>
        ''' Clear the comment of the RichTextbox.
        ''' </summary>
        ''' <remarks></remarks>
        Public Overloads Sub Clear()
            m_FileName = ""
            m_blnInit = False
            MyBase.Clear()
        End Sub

        ''' <summary>
        ''' Before the line added into the RichTextbox.
        ''' </summary>
        ''' <param name="line">The string to add.</param>
        ''' <remarks></remarks>
        Protected Overridable Sub OnBeforeLineAdded(ByVal line As String)
            Dim blaea As New BeforeLineAddEventArgs(line, Me.Font, Me.ForeColor)
            RaiseEvent BeforeLineAdd(Me, blaea)
            If blaea.Cancel = False Then
                AddLine(blaea.Text, blaea.Font, blaea.Color)
            End If
        End Sub

        ''' <summary>
        ''' Add a line of string to the RichTextbox.
        ''' </summary>
        ''' <param name="line">The string to add.</param>
        ''' <param name="font">The font of the string.</param>
        ''' <param name="color">The fore color of the string.</param>
        ''' <remarks></remarks>
        Private Sub AddLine(ByVal line As String, ByVal font As Drawing.Font, ByVal color As Drawing.Color)
            SelectionFont = font
            SelectionColor = color
            AppendText(line & vbCr)
        End Sub

        ''' <summary>
        ''' On encoding menu item check.
        ''' </summary>
        ''' <param name="sender">The RichTextbox object.</param>
        ''' <param name="e">EventArgs object.</param>
        ''' <remarks></remarks>
        Private Sub OnContextMenuItemsClick(ByVal sender As Object, ByVal e As EventArgs)
            Dim mi As Windows.Forms.MenuItem
            Dim enc As Text.Encoding
            If TypeOf sender Is Windows.Forms.MenuItem Then
                mi = CType(sender, Windows.Forms.MenuItem)
                If m_htEncodings.Contains(mi.Text) = True Then
                    enc = m_htEncodings.Item(mi.Text)
                    Load(m_FileName, enc)
                    RadioCheckEncodingItem(enc)
                End If
            End If
        End Sub

#Region " EventArgs Class "

        ''' <summary>
        ''' The base class of the event args in RichText.
        ''' </summary>
        ''' <remarks></remarks>
        <ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
        Public MustInherit Class CountRichTextBoxEventArgs
            Inherits EventArgs

            Private m_Cancel As Boolean

            ''' <summary>
            ''' Cancel all next operator flag.
            ''' </summary>
            ''' <value></value>
            ''' <returns>Cancel all next operator flag.</returns>
            ''' <remarks></remarks>
            Public Property Cancel() As Boolean
                Get
                    Return m_Cancel
                End Get
                Set(ByVal Value As Boolean)
                    m_Cancel = Value
                End Set
            End Property

            ''' <summary>
            ''' Create instance.
            ''' </summary>
            ''' <remarks></remarks>
            Protected Sub New()
                MyBase.New()
                m_Cancel = False
            End Sub

        End Class

        ''' <summary>
        ''' Before the line added into the RichTextbox.
        ''' </summary>
        ''' <remarks></remarks>
        Public Class BeforeLineAddEventArgs
            Inherits CountRichTextBoxEventArgs

            Private m_Font As Drawing.Font
            Private m_Color As Drawing.Color
            Private m_Text As String

            ''' <summary>
            ''' The font of the string to add.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Font() As Drawing.Font
                Get
                    Return m_Font
                End Get
                Set(ByVal Value As Drawing.Font)
                    m_Font = Value
                End Set
            End Property

            ''' <summary>
            ''' The color of the string to add.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Property Color() As Drawing.Color
                Get
                    Return m_Color
                End Get
                Set(ByVal Value As Drawing.Color)
                    m_Color = Value
                End Set
            End Property

            ''' <summary>
            ''' The text of the string to add.
            ''' </summary>
            ''' <value></value>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public ReadOnly Property Text() As String
                Get
                    Return m_Text
                End Get
            End Property

            ''' <summary>
            ''' Create instance.
            ''' </summary>
            ''' <param name="Text">The text of the string to add.</param>
            ''' <param name="Font">The font of the string to add.</param>
            ''' <param name="Color">The color of the string to add.</param>
            ''' <remarks></remarks>
            Public Sub New(ByVal Text As String, ByVal Font As Drawing.Font, ByVal Color As Drawing.Color)
                MyBase.New()

                m_Text = Text
                m_Font = Font
                m_Color = Color
            End Sub

        End Class

#End Region

    End Class

End Namespace
